
package com.hlkj.pay.app.merchant.ext.impl.lakala.ext;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderQueryContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelRefundPayOrderContext;
import com.hlkj.pay.app.merchant.ext.impl.lakala.LakalaScenePayOrderExtPt;
import com.hlkj.pay.app.merchant.ext.impl.lakala.constant.LakalaConstant;
import com.hlkj.pay.app.merchant.ext.impl.lakala.constant.LakalaExtConstant;
import com.hlkj.pay.app.merchant.ext.impl.lakala.dto.LakalaAppChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.lakala.dto.LakalaConfig;
import com.hlkj.pay.app.merchant.ext.impl.lakala.dto.req.LakalaPayReq;
import com.hlkj.pay.app.merchant.ext.impl.lakala.dto.resp.LakalaPayOrderRes;
import com.hlkj.pay.app.merchant.ext.impl.lakala.dto.resp.LakalaPayRes;
import com.hlkj.pay.app.merchant.ext.impl.lakala.utils.LKLSDK;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.order.PayOrderDO;
import com.hlkj.pay.util.MerchantUtils;
import com.hlkj.pay.vo.order.req.PayOrderCommonParamReq;
import com.lkl.laop.sdk.exception.SDKException;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 条码支付，商户扫用户二维码收款
 * 
 * @author HlpayTeam
 * @date 2024/11/18 13:08
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = LakalaExtConstant.SCAN_PAY)
public class LakalaScanPayOrderExtPt extends LakalaSceneCommonPayOrder implements LakalaScenePayOrderExtPt {

    @Override
    public void submitChannelPayOrder(ChannelPayOrderContext channelPayOrderContext) {
        // 配置转换
        LakalaConfig lakalaConfig = lakalaConfig(channelPayOrderContext.getProviderChannelConfigDO(),channelPayOrderContext.isTest());
        PayOrderDO payOrderDO = channelPayOrderContext.getPayOrderDO();
        MerchantAppChannelDO merchantAppChannelDO = channelPayOrderContext.getMerchantAppChannelDO();
        LakalaAppChannelParams lakalaAppChannelParams = lakalaAppChannelParams(merchantAppChannelDO);
        try {
            String openapiDomain = openapiDomain(channelPayOrderContext.isTest());
            LKLSDK.init(lakalaConfig, openapiDomain);
            Map<String, Object> params = new HashMap<>();
            params.put("merchant_no", lakalaAppChannelParams.getMerCupNo());
            params.put("term_no", lakalaAppChannelParams.getTermId());
            params.put("out_trade_no", payOrderDO.getPayOrderNo());
            PayOrderCommonParamReq.Extra extra = JsonUtils.parseObject(payOrderDO.getExtra(), PayOrderCommonParamReq.Extra.class);
            params.put("auth_code", extra.getAuthCode());
            params.put("total_amount", MerchantUtils.YuanToFen(payOrderDO.getAmount()).toString());
            Map<String, Object> location_info = new HashMap<>();
            location_info.put("request_ip",payOrderDO.getClientIp());
            params.put("location_info", location_info);
            params.put("subject", payOrderDO.getSubject());
            params.put("notify_url", channelPayOrderContext.getNotifyUrl());
            LakalaPayReq lakalaPayReq = new LakalaPayReq();
            lakalaPayReq.setReq_time(reqTime());
            lakalaPayReq.setReq_data(params);
            String body = JsonUtils.toJsonString(lakalaPayReq);
            log.info("拉卡拉条码支付请求参数:{}", body);
            String response = LKLSDK.httpPost(openapiDomain(channelPayOrderContext.isTest()) + LakalaConstant.MERCHANT_PAY_ORDER_QR, body, lakalaConfig.getAppId());
            log.info("拉卡拉条码支付返回参数:{}", JsonUtils.toJsonString(response));
            LakalaPayRes<LakalaPayOrderRes> lakalaRes = JsonUtils.parseObject(response, new TypeReference<LakalaPayRes<LakalaPayOrderRes>>() {
            });

            LakalaPayOrderRes respData = lakalaRes.getResp_data();
            if (LakalaConstant.QR_SUCCESS_CODE.equals(lakalaRes.getCode())) {
                // channelPayOrderContext.setPayInfo(fuYouPayOrderResultDto.getQr_code());
                // channelPayOrderContext.setPayDataType("pay_url");
                channelPayOrderContext.setChannelOrderNo(respData.getTrade_no());
                channelPayOrderContext.setChannelOrderId(respData.getLog_no());
                channelPayOrderContext.setInsOrderNo(respData.getAcc_trade_no());
            }
            else {
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                if (StringUtils.hasText(lakalaRes.getMsg())) {
                    channelPayOrderContext.setRemark(lakalaRes.getMsg());
                }
                else {
                    channelPayOrderContext.setRemark("拉卡拉提交条码支付查询返回错误信息为空,错误码为:" + lakalaRes.getCode());
                }
            }
        }
        catch (SDKException e) {
            e.printStackTrace();
            log.error("拉卡拉提交条码支付请求失败 lakalaConfig:{},message:{}", JsonUtils.toJsonString(lakalaConfig), e.getMessage(), e);
            channelPayOrderContext.setRemark("拉卡拉提交条码支付请求失败,失败信息" + e.getMessage());
            channelPayOrderContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantAccessQueryContext.setAccessStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.APPROVE_REFUSE);
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("拉卡拉提交条码支付请求失败 message:{}", e.getMessage(), e);
            channelPayOrderContext.setRemark("拉卡拉提交条码支付请求失败,失败信息" + e.getMessage());
            channelPayOrderContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantAccessQueryContext.setAccessStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.APPROVE_REFUSE);
        }
    }

    @Override
    public void queryChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonQueryChannelPayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void closeChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonCloseChannelPayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void queryChannelClosePayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonQueryChannelClosePayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void refundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        commonRefundChannelPayOrder(channelRefundPayOrderContext);
    }

    @Override
    public void queryRefundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        commonQueryRefundChannelPayOrder(channelRefundPayOrderContext);
    }

    @Override
    public boolean refundApply(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        return true;
    }

    @Override
    public CommonResult<String> channelOrderCode(ChannelPayOrderContext channelPayOrderContext) {
        return CommonResult.success();
    }
}
